﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

#if WPF
namespace Silverlight.Hosting.Wpf.Interop
#else
namespace Silverlight.Hosting.Interop
#endif
{
    /// <summary>
    /// 
    /// </summary>
    public interface IDownloadUrlCallback
    {
        /// <summary>
        /// Notifies the Silverlight plug-in of the completion of a download.
        /// </summary>
        /// <param name="stream">The stream containing the downloaded data.</param>
        void NotifyDownloadSuceeded(Stream stream);

        /// <summary>
        /// Notifies the Silverlight plug-in of the failure of the download.
        /// </summary>
        void NotifyDownloadFailed();
    }

    internal class DownloadUrlCallback : IDownloadUrlCallback
    {
        private Control _owner;
        private SafeComObject<IXcpControlDownloadCallback> _callback;

        internal DownloadUrlCallback(Control owner, SafeComObject<IXcpControlDownloadCallback> callback)
        {
            _owner = owner;
            _callback = callback;
        }

        public void NotifyDownloadSuceeded(Stream stream)
        {
            if (_callback == null || _owner == null)
            {
                if (stream != null) stream.Dispose();
                throw new InvalidOperationException("A notification has alread been sent.");
            }

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            try
            {
                _owner.BeginInvoke(new Action<SafeComObject<IXcpControlDownloadCallback>>((callback) =>
                {
                    using (callback)
                    {
                        callback.Object.OnUrlDownloaded(HRESULT.S_OK, new NativeStream(stream));
                    }
                }), _callback);
            }
            catch
            {
                stream.Dispose();
            }

            _callback = null;
            _owner = null;
        }

        public void NotifyDownloadFailed()
        {
            if (_callback == null || _owner == null)
            {
                throw new InvalidOperationException("A notification has alread been sent.");
            }

            _owner.BeginInvoke(new Action<SafeComObject<IXcpControlDownloadCallback>>((callback) =>
            {
                using (callback)
                {
                    callback.Object.OnUrlDownloaded(HRESULT.S_FALSE, null);
                }
            }), _callback);

            _callback = null;
            _owner = null;
        }
    }
}
